
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]#"


#define MAXARGC 128
char * g_argv[MAXARGC];
int g_argc=0;
char cwd[1024];
char cwdenv[1024];
const char* GetUserName()
{
    const char*  name=getenv("USER");

    return name==NULL ? "None":name;
}

const char* GetHostName()
{
    const char* hostname=getenv("HOSTNAME");

   return  hostname==NULL?"None":hostname; 
}

const char * GetPWD()
{
   // const char* PWD=getenv("PWD");
   const  char* PWD=getcwd(cwd,sizeof(cwd));
   if(PWD!=NULL)
   {
     snprintf(cwdenv,sizeof(cwdenv),"PWD=%s",cwd);
     putenv(cwdenv);
   }
    return PWD==NULL?"None":PWD;
}

const char * GetHome()
{
  const char *home=getenv("HOME");
  return home==NULL ?"":home;
}

std::string DirName(const char *pwd)
{
 #define SLASH "/"
 std::string dir=pwd;

 if(dir==SLASH)
 {
   return SLASH;
 }
 std::size_t pos=dir.rfind(SLASH);
 if(pos==std::string::npos)return "bug";

 return dir.substr(pos+1);
}



void MakeComandline(char cmd_prompt[],int size)
{
  snprintf(cmd_prompt,size,FORMAT,GetUserName(),GetHostName(),DirName(GetPWD()).c_str());
}

void printfCommandlPrompt()
{
  char prompt[COMMAND_SIZE];
  MakeComandline(prompt,sizeof(prompt));

  printf("%s",prompt);
  fflush(stdout);
}


bool GetCommandline(char *out,int size)
{
  char *c=fgets(out,size,stdin);
  if(c==NULL) return false;
  out[strlen(out)-1]=0;
  if(strlen(out)==0)
    return false;

  
  return true;
}

bool CommandParse(char *command)
{
  #define SEP " "
  g_argc=0;
  g_argv[g_argc++]=strtok(command,SEP);

  while((bool)(g_argv[g_argc++]=strtok(nullptr,SEP)));
  g_argc--;

  return g_argc>0?true:false;
}

void prinfArgc()
{
  int i=0;
  for(i=0;g_argv[i];i++)
  {
     printf("argv[%d]->%s\n",i,g_argv[i]); 
  }
    printf("agrc %d\n",g_argc);
}

int execute()
{
  
   pid_t id=fork();
   if(id==0)
   {
     execvp(g_argv[0],g_argv);
     exit(1);
   }
  pid_t rid=waitpid(id,NULL,0);
  (void)rid;

  return 0;
}

bool  checkAndExecubuild()
{
  std::string cmd=g_argv[0];
  if(cmd=="cd")
  {
    if(g_argc==1)
    {
      std::string home=GetHome();
      if(home.empty())return true;
      chdir(home.c_str());
    }
    else{
      std::string where=g_argv[1];
      if(where=="~")
      {

      }
      else if(where=="-")
      {

      }
      else{
        chdir(where.c_str());
      }

    }

    return true;
  }
  return false;

    
}
int main()
{


  while(1)
 {
  printfCommandlPrompt();
  
 // printf("[%s@%s %s]#\n",GetUserName(),GetHostName(),GetPWD());

  char command[COMMAND_SIZE];
  if(!GetCommandline(command,sizeof(command)))
  {
    continue;
  }
   // printf("echo %s\n",command);
  if(!CommandParse(command))
  {
    continue;
  }
  // prinfArgc();


 if(checkAndExecubuild())
 {
   continue;

 }

  execute();

}


  
 // char *c=fgets(command,sizeof(command),stdin);
 //
 // if(c==NULL)
 //   return 1;
 //
 // command[strlen(command)-1]=0;
 //
 // printf("echo %s\n",command);
  
  

  return 0;
}
